ANÁLISIS DE SINIESTRALIDAD

CUNEF MUCD (2021/22)

EDA

Diccionario de datos

A continuación mostramos el diccionario de datos con el que trabajaremos. Este diccionario de datos se corresponderá con los datos con los que trabajaremos después de modificar los datos originales

Definición del problema

Los gobiernos federal, provincial y territorial de Canadá trabajan para mejorar la seguridad vial con el fin de reducir el número de víctimas mortales.

Teniendo en cuenta todas las variables que tenemos, se quiere predecir si habrá fallecimientos o no. El momento a evaluar el modelo será una vez producido el accidente. Es decir, evaluaremos el modelo teniendo en cuenta unicamente las variables conocidas en el instante en el que se produce una colisión. Todos aquellos registros conocidos a posteriori no serán incluidos en nuestro modelo. La finalidad del modelo es realizar una predicción con el mayor porcentaje de acierto posible, que nos indique en el momento que se produza un accidente si habra al menos un fallecido, o bien han sobrevibido todos los involucrados en el mismo.

Para ello, disponemos de un conjunto de datos proporcionado por La base de datos nacional de colisiones de Transport Canada (NCDB). Dicha base, contiene datos sobre todas las colisiones de vehículos de motor notificadas en Canadá que las provincias y territorios proporcionan cada año (1999-2014).

Librerías

Se importan las librerías necesarias para poder llevar a cabo este notebook. Ajustamos las opciones de visualización de los datos para poder ver todas las columnas del dataset

Funciones

Cargamos FUNCIONES. De esta manera, importamos las funciones necesarias en este notebook del archivo FUNCIONES.py, donde se encuentran todas las funciones creadas que nos ayudan a alcanzar nuestro objetivo con su correspondiente explicación .

Lectura del fichero csv

Lectura de los datos proporionados en formato .csv. Mostramos las 8 primeras filas del dataset para realizar una primera observación

Observamos la clase de las variables que tiene nuestro dataset

Mostramos las dimensiones del dataset con el que se va a trabajar

Comprobamos los valores únicos que hay en cada una de las columnas haciendo uso de la función valores_unicos. Si en una variable existen más de 'k' categóricas únicas, no te las muestra. Por lo tanto, elegimos un 'k' elevado para que nos enseñe todo.

Verificamos la existencia de entradas de datos duplicadas.

Después de haber visto de manera rápida el dataset, las modificaciones que llevaremos a cabo serán las siguientes:

En primer lugar. como hemos explicado anteriormente en las modificaciones que ibamos a realizar, nuestro objetivo es prededir si existen victimas mortales o no en caso de accidente, sin tener en cuenta el nº de posibles fallecidos. Para ello, nos interesa tener una única fila por cada accidente. De esta manera evitamos el uso de filas inncesarias en las que solo varían datos que no aportan información relevante. Filtraremos el dataset por la variable P_PSN, la cual nos indica la posición de la persona en el accidente. Lo filtraremos por el valor "11" ya que este valor indica la posición de conductor. Elegimos esta posición puesto que siempre hay al menos un conductor (sea del vehículo que sea) involucrado en cualquier colisión.

Modificaciones en el dataset

Cambiamos los valores "U", "UU", "UUU" y "UUUU" (Unknown) por NaN

Ahora, vamos a ver cuantos valores no nulos hay en cada una de nuestras columnas mediante 'msno.bar'.

Por otro lado, observamos qué porcentaje de valores missing tienen las columnas con las que trabajaremos

El mayor porcetanje de valores missing, perteneciente a la columna P_SAFE no supera el 12%.

Unificamos valores duplicados, pasamos las variables C_MNTH, C_WDAY, C_HOUR, C_VEHS, V_YEAR, P_AGE a numéricas y eliminamos filas repetidas

A continuación, llamamos a la función unificar con el fin de modificar nuestro dataset unificando los valores "repetidos" (ej: 12, "12" = "12"). Por otra parte, transformar las columnas seleccionadas a númericas. A partir de ahora, los valores de nuestro dataset serán de la forma "01", "02" y así sucesivamente.

Comprobamos el nuevo número de filas duplicadas.

Efectivamente, vemos que sí, y eliminamos dichas filas mediante drop_duplicates()

Las nuevas dimensiones del dataset son:

Llamamos de nuevo a la función valores_unicos y comprobamos que ya no hay valores repetidos en nuestras columnas

Mostramos ahora las clases de las variables para ver que se han cambiado correctamente.

Datos incorrectos

Vamos a crear una variable en la que nos apoyaremos para tomar una decisión pero no la consideraremos para el análisis. Esta variable es diferencia e indicará los años que han pasado desde año del modelo del vehículo (V_YEAR) hasta el accidente. Lo que buscamos es que si alguna de las diferencias es menor que 0, eso querrá decir que el año del modelo del vehículo es mayor que el año del accidente.

Para ver si tenemos valores negativos en la columna diferencia haremos uso de la función valores_unicos.

Efectivamente, hay valores negativos (-1 y -2). Luego, eliminamos las filas el año de colisión es menor que el año del modelo del vehículo. Para ello crearemos un bucle el cual irá recorriendo los índices de la lista df_pd_data[diferencia]. En el momento que encuentre un valor que sea negativo y, además no sea nulo, entonces añadirá el ínidice de la fila a la lista de índices. Esto nos servirá para después hacer un .drop sobre todos los ínidices de las filas en las que eso ocurre.

Veamos cuántos valores vamos a eliminar.

Eliminamos tanto las filas calculadas como la columna diferencia, la cual ya no nos interesa para el análisis

Vamos a modificar las variables MNTH, WDAY y HOUR

La idea de modificar estas variables es convertirlas en cíclias, es decir, que el día de la semana 7 y el día de la semana 1 estén cerca matemáticamente hablando. Si no hacemos esto estaremos asegurando que domingo es más grande que lunes y esto no tiene sentido. Es por ello que haremos uso de las funciones coseno y seno para codificar las variables mencionadas cíclicamente. Para ello, llamamos a la función codificacion_ciclica

A nuestro dataset se añadiran 6 columnas nuevas de tipo float correspondientes al seno y al coseno de cada una de las variables elegidas.

A continuación mostramos un ejemplo de la codificación de la variable mes (C_MNTH) con una muestra de 40 datos. En el gráfico se observa claramente la forma cíclica de la variable.

Mostramos cuantos valores missing tenemos por cada columna para ver que después de todas las modificaciones realizadas. Verficamos que los valores missing siguen formando parte de nuestros datos.

Mostramos un análisis descriptivo de todas las variables del dataset. Al tener pocas variables numéricas y muchos valores missing, no nos va a portar gran información.

Dada la gran cantidad de valores nulos, la mayoría de datos estadísticos son NaN

Análisis de la variable objetivo

Atendemos a la distribución de la variable objetivo. Creamos un data frame en el que mostramos cuántos valores tenemos en cada clase de la variable objetivo y el porcentaje.

Mostramos gráficamente la distribución de la variable objetivo

Como podemos observar, más del 98% de los datos de nuestra variable Taget corresponde a la categoría "02" = Ningún fallecido. A la hora de realizar el modelo tendremos que tener en cuenta esta distribución dado que el dataset esta desbalanceado

Distribución respecto a otras variables

Distribución de la variable objetivo en función de otras variables del dataset.

Realizamos la distribución de nuestra variable objetivo respecto aquellas variables que consideramos más importantes para analizar.

C_SEV ~ C_WDAY

C_SEV ~ C_HOUR

C_SEV ~ C_MNTH

C_SEV ~ C_CONF

C_SEV ~ C_WTHR

Gráficos de distribuciones de las variables

Realizamos un gráfico de barras para analizar la distribución de las la variable objetivo en función del resto de variables. Para ello, llamamos a la función graf_barras. El gráfico nos mosotrara la distriubción de cada una de las variables a la izquierda. A la derecha, la distribución de la variable target en función de cada una de las variables.

Elimminamos las colummnas de seno y coseno creadas anteriormente para realizar el plot en cuestión.

Gracias a estos gráficos podemos conocer la distribución de cada una de las variables, el número de valores nulos existentes en cada una de ellas y el comportamiento de nuestra variable objetivo respecto a cada valor tomado por la variable en cuestión. Como se puede observar, en la mayoría de variables a excepción de aquellas relacionadas con la fecha de colisión, la distribución predomina para unos pocos valores. Algunas disitribuciones las comentaremos posteriormente. Por otro lado, como ya habiamos desmostrado con anterioridad para una inmensa mayoría de valores predomina el valor 2 de nuestra variable objetivo, correspondiente a ningún fallecido. A modo de excepción, podemos apreciar como es lógico, que cuando la variable P_ISEV (Intervención médica) toma el valor 03(Fallecimiento en el acto) corresponden a accidentes en los que según nuestra variable target ha tenido lugar al menos un fallecimiento (2)

Mostramos el gráfico de correlaciones de las variables númericas.

Filtrado, descartado y agrupación de datos para DATASET FINAL

Una vez realizado el filtrado sobre nuestro dataset, decidimos hacer una selección de columnas con las que trabajaremos para llevar a cabo el modelo final.

Hemos descartado todas las columnas correspondientes a elementos de vehículos y de personas. Es decir, todas las colummnas que contienen información sobre los vehículos involucrados (V ...) y personas (P ...) quedan excluidas de nuestro conjunto de datos final. Esta exclusión se debe a que, como se ha indicado en la definición del problema, nuestro modelo tratará de predecir si hay fallecimientos o no en el momento exacto en el que se produce un accidente.

Esto significa que toda la información conocida después de ese instante, es información que no conocemos. Hasta que se produce una investigación, datos como el año del modelo del vehículo, o si ha sido necesaria intervención medica, o bien cualquier otro tipo de información descripitiva, son datos desconocidos para nosotros.

En el momento en el que se produce una colisión solo se tiene información acerca de aquello que este relacionado directamente con la colisión, como puede ser la configuaración de la carretera o el número de vehiculos involucrados, o bien datos .... como la fecha o las condiciones climáticas.

Por otra parte, al transformar las variables C_MNTH, C_WDAY y C_HOUR a cíclicas nos quedamos con aquellas columnas correspondientes a dicha transformación (seno y coseno) y eliminamos de nuestro dataset las columnas originales.

Distribución normalizada

Por último, tras haber realizado los descartes y con nuestro dataset ya filtrado prodecemos a realizar una agrupación de nuestros datos en función de cada variable y su distribución respecto a la variable objetivo, con el fin de reducir el número de categorias para que el modelo trabaje de forma más eficiente.

En el caso de la variable C_CONF(Configuarción de la colisión) hemos agrupado las posibles opciones de la variable en 4 categorías correspondientes a la cantidad y la dirección de los vehículos involucrados. (Vease diccionario de datos)

Para la variable C_WTHR(Clima) realizamos la agrupación mediante una distinción entre clima favorable para la conducción y clima adverso. Como se observa en eñ gráfico previamente mostrado, la mayoría de colisiones tienen lugar en la categoría 01 de la variable, correspondiente un día despejado y soleado. (Vease diccionario de datos)

En la columna C_RALN(Alineación de la carretera) como se aprecia en la distibución respecto a la variable objetivo, la mayoría de accidentes tienen lugar en carreteras rectas, sin curvas ni pendientes (01), por lo tanto hemos agrupado la variable en dos categorías: carretera recta y sin pendiente y por otro lado carretera con curvas, pendiente etc. (Vease diccionario de datos)

En La variable C_SUR(Superficie) hemos realizado una distinción en dos grupos. Uno correspondiente a escensarios en los que la carretera está seca, en estado normal, cuando se producen la mayoria de colisiones si observamos la distribución (01) y un segundo grupo, el cual corresponde a escenarios donde la carretera se encuentra mojada, nevada etc. (Vease diccionario de datos)

En el caso de la variable C_TRAF(Tráfico) hemos realizado una agrupación según lo observado en las dsitribuciones. Por una parte mantenemos aquellos casos en el que las señales de trafico funcionan con completa normalidad (01), y por otro lado, una distinción para los casos en los que no existe nigún tipo de control (18 en el dataset original) y aquellos escenarios donde ciertas reestricciones como pasos de cebra, colegios infantiles cerca etc. (Vease diccionario de datos)

La última agrupación la realizamos sobre la variable C_RCFG(Configuración de la carretera). Hemos distinguido dos grupos dentro de las categorias existentes. Una selección corresponde a carreteras sin nigún tipo de intersección, y el segundo grupo, a aquellas carreteras o localizaciones en las existan intersecciones, o cualquier otro tipo de elemento que altere la carretera, túneles, puentes, raíles etc. (Vease diccionario de datos)

Realizamos las agrupaciones correspondientes para cada variable

Mostramos los valores únicos que nos quedan en cada una de las columnas. Se puede observar como se ha reducido notablemente el número de categorias posibles en cada una de las variables transformadas.

Introducimos una variable aleatoria con el fin de evaluar de manera más precisa la importancia de las variables. Es decir, a la hora de interpretar la importancia de las variables en nuestro modelo final, aquellas cuya significación esté por debajo de la variable aleatoria creada significará que no aportan información a nuestro modelo de predicción.

Mostramos a continuación, el dataset final con el que evaluaremos los modelos